home *** CD-ROM | disk | FTP | other *** search
- I am posting the source code since among the people
- who requested for the source code, two of them are
- not reach-able from my system. Fortunately it's not a
- big program. Sorry for the inconvenience.
- ***
- /*
- * program: nfff.c
- *
- * a filter for NFF (Neutral File Format)
- * nfff [infile]
- * input: infile.nff or stdin
- * output: stdout
- *
- * input items other than polygons are copied to output directly.
- * for polygons that have 2 or more identical vertices, the redundant
- * vertices are filtered out and the "p <vert_count>" lines of
- * the polygons are adjusted properly.
- *
- * the vertices degeneration cases occur in data produced by some
- * automatic nff generation program when the resolution/prec. of
- * generation exceeds that of the floating point format.
- *
- * definition of NFF: see nff.def
- * bugs:
- * (1) handles polygons only. break if there are other obj. types
- * (2) MAX_VERT may cause trouble
- *
- * Fri Dec 2 16:41:27 EST 1988
- * pkh@vap
- *
- * bugs fixed:
- *
- */
- #include <stdio.h>
- #include <math.h>
- /* #include "/usr/pkh/include/all.h" */
- /* #include "/usr/pkh/include/def3d.h" */
-
- /* from "def3d.h" */
- typedef struct pt3d_struct {
- float x, y, z;
- } pt3d, *pt3d_t;
- #define FPRINT3d(fp, pt, newline) do { \
- if (newline) \
- fprintf(fp, "%g %g %g\n", pt.x, pt.y, pt.z); \
- else \
- fprintf(fp, "%g %g %g", pt.x, pt.y, pt.z); \
- } while (0)
- #define FSCAN3d(fp, pt) do { \
- fscanf(fp,"%f %f %f", &(pt.x), &(pt.y), &(pt.z)); \
- } while(0)
- #define ASSIGN3d(p0, p1) do {p0.x=p1.x; p0.y=p1.y; p0.z=p1.z;} while(0)
- #define EQ3d(p0, p1) ((p0.x==p1.x)&&(p0.y==p1.y)&& (p0.z==p1.z))
-
- /* from "all.h" */
- int debug;
- #define POW2(y) (1<<y)
- #define ERROR_MSG_LENGTH (200)
- #define DEBUG(arg) \
- do { \
- char msg[ERROR_MSG_LENGTH]; \
- if (debug) { \
- sprintf arg; \
- fprintf(stderr, "%s", msg); \
- } \
- } while (0)
- #define ERROR(arg) \
- do { \
- char msg[ERROR_MSG_LENGTH]; \
- sprintf arg; \
- fprintf(stderr, "%s", msg); \
- exit(0); \
- } while (0)
-
- #define MAX_VERT POW2(12) /* 4k verts per poly */
- pt3d *v; /* array of dim MAX_VERT */
-
- FILE *nfffile;
- char infile[25];
-
- /*
- * for statistics
- */
- int total_byte; /* total byte allocated */
- int poly_id;
-
- /*
- * copy to end of line
- */
- copy_line(ifp, ofp)
- FILE *ifp, *ofp;
- {
- char c;
- do {
- putc((c=getc(ifp)), ofp);
- } while (c!='\n');
- }
-
- int read_poly(fp)
- FILE *fp;
- {
- int tv;
- int i;
-
- fscanf(fp, "%d", &tv);
-
- for (i = 0; i < tv; i++) {
- FSCAN3d(fp,(v[i]));
- }
- return (tv);
- }
-
- /*
- * filter out degenerated (redundant) vertices
- * and return the true vert count.
- * complain when polygon has less than 3 vert
- */
- int vert_filter(in_vert)
- int in_vert;
- {
- int head, tail;
- int tv, skip;
-
- /*
- * filter out degenerated vertices. head points to the verified vert,
- * tail scans down the vert list for new vert.
- */
- head = 0; /* points to v[0] */
- tail = head + 1; /* points to v[1] */
- tv = 1; /* count one vert already (v[0]) */
- skip = 0; /* "skip occured" flag */
- do {
- while (EQ3d((v[head]), (v[tail]))) {
- tail++;
- if (tail == in_vert)
- goto last_vert;
- skip = 1;
- }
- if (skip) {
- ASSIGN3d((v[head + 1]), (v[tail]));
- }
- head++;
- tail++;
- } while (tail < in_vert);
-
- /* head now points to the last valid vert. compare last and first */
- last_vert:if (EQ3d((v[0]), v[head]))
- tv = head;
- else
- tv = head + 1;
- if (tv < 3) {
- ERROR((msg, "poly %d has less than 3 vert\n", poly_id));
- write_polygon(stderr, tv); /* write vert */
- }
- if (debug) {
- write_polygon(stderr, tv); /* write vert */
- }
- return (tv);
- }
-
- /*
- * write out the cleaned-up polygons in nff format
- * also print out the poly id
- */
- write_polygon(fp, ply_vert)
- FILE *fp;
- int ply_vert;
- {
- int j;
-
- fprintf(fp, "# p%d\np %d\n", poly_id, ply_vert);
- for (j = 0; j < ply_vert; j++) {
- FPRINT3d(fp, (v[j]), 0);
- fprintf(fp, "\n");
- }
- }
-
- /*
- * for polygons: read-filter-write
- * for the rest: read-write
- */
- read_write(ifp, ofp)
- FILE *ifp, *ofp;
- {
- char key[20];
- int in_vert, out_vert;
-
- /* read "key" */
- while (fscanf(ifp, "%s", key) != EOF) {
-
- DEBUG((msg, "get key %s\n", key));
- if (strcmp(key, "p") == 0) {
- in_vert = read_poly(ifp);
- out_vert = vert_filter(in_vert);
- write_polygon(ofp, out_vert);
- poly_id++;
- } else {
- fprintf(ofp, "%s ", key);
- copy_line(ifp, ofp);
- }
- };
- }
-
- init()
- {
- int new_byte;
-
- new_byte = sizeof(pt3d) * MAX_VERT;
- total_byte += new_byte;
- v = (pt3d_t) malloc(new_byte);
- DEBUG((msg, "v alloc %3dB; total %5dB\n", new_byte, total_byte));
- if (v == NULL)
- ERROR((msg, "v array alloc err\n"));
-
- poly_id = 0;
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- if (argc == 1) {
- nfffile= stdin;
- }
- else if (argc == 2) {
- /* ap
- } pend .nff suffix */
- sprintf(infile, "%s.nff", argv[1]);
- if ((nfffile= fopen(infile, "r")) == NULL) {
- ERROR((msg, "input file %s not found\n", infile));
- exit(1);
- }
- } else {
- ERROR((msg, "Usage: %s [file].nff\n", argv[0]));
- exit(1);
- }
-
- debug = 0;
-
- init();
-
- fprintf(stdout, "#\n# polygons filtered by nfffilter program\n");
- fprintf(stdout, "# date:\n#\n");
- read_write(nfffile, stdout);
- }
-